import  Matrix from "Matrix.js";

//多元线性回归
export default class MLR{
    Y;
    X;
    mtrx  = new Matrix();
    //X 的转置
    Xt;
    // Xt * X的逆矩阵
    InvOfXtX;
    //系数
    Coef;
    //帽子矩阵
    H;
    //拟合值
    fittedY;
    //残差
    R;

    constructor(X,Y){
        this.X=X;
        this.Y=Y;
        this.Xt = this.mtrx.T(this.X);
        this.InvOfXtX = this.mtrx.InvByLU(this.mtrx.Mul(this.Xt,X));
    }

    //回归系数 普通最小二乘法
    CoefByOLS(){
        let tmp = this.mtrx.Mul(this.InvOfXtX,this.Xt);
        this.Coef= this.mtrx.Mul(tmp,this.Y);
        return this.Coef;
    }

    //帽子矩阵
    getH(){
        let tmp = this.mtrx.Mul(this.X,this.InvOfXtX);
        this.H = this.mtrx.Mul(tmp,this.Xt);
        return this.H;
    }

    //普通残差
    Residual() {
        if (!this.H)
            this.getH();
        if(!this.fittedY)
            this.Fitted();
        let tmp = this.mtrx.MulNum(this.fittedY,-1);
        this.R = this.mtrx.add(this.Y,tmp);
        return this.R;
    }

    //求拟合值
    Fitted(){
        if (!this.H)
            this.getH();
        this.fittedY = this.mtrx.Mul(this.H,this.Y);
        return this.fittedY;
    }
    //残差平方和
    RSS(){
        let sum =0;
        if(!this.R)
            this.Residual();
        for(let e of this.R)
            sum += e[0]*e[0]
        return sum;
    }
}